import { isNull } from 'util'
import { All, Injectable } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { Borrow } from 'src/entity/Borrow'
import { Asset } from 'src/entity/Asset'
import { Task } from 'src/entity/Task'
import { Connection, IsNull, Repository } from 'typeorm'
import { v4 as uuidV4 } from 'uuid'
import { BusinessException } from 'src/common/exceptions/business.exception'

@Injectable()
export class BorrowService {
  constructor(
    @InjectRepository(Borrow)
    private borrowRepository: Repository<Borrow>,
    private connection: Connection,
  ) { }

  async add(data: Borrow) {
    const borrowCode = 'A' + uuidV4()
    data.borrowCode = borrowCode
    data.borrowOutStatus = '0'
    data.borrowInStatus = '0'
    data.borrowInBranch = data.receiveBranch
    data.borrowInBranchId = data.receiveBranchId

    await this.connection.transaction(async (manager) => {
      // const sqlData: Borrow = await this.borrowRepository.save(data)
      const assetSqlData = await manager.findOne(Asset, {
        where: {
          assetCode: data.assetCode,
          branchId: data.borrowOutBranchId,
          isDelete: IsNull(),
        },
      })
      if (!assetSqlData)
        throw new BusinessException('选择资产不存在或不属于该部门')
      const sqlData: Borrow = await manager.save(Borrow, data)
      const taskData = new Task()
      taskData.receiveBranch = sqlData.receiveBranch
      taskData.receiveBranchId = sqlData.receiveBranchId
      taskData.receivePerson = sqlData.receivePerson
      taskData.receivePersonId = sqlData.receivePersonId
      taskData.receiveCode = sqlData.borrowCode
      taskData.receiveDate = sqlData.receiveDate
      taskData.receiveBranch = sqlData.borrowOutBranch
      taskData.receiveOutBranchId = sqlData.borrowOutBranchId
      taskData.taskName = sqlData.borrowName
      taskData.taskInStatus = '0'
      taskData.taskOutStatus = '0'
      taskData.taskType = '3'
      await manager.insert(Task, taskData)
    })

    return data
  }

  async del(id: number) {
    await this.connection.transaction(async (manager) => {
      const sqlData = await this.borrowRepository.findOne({
        where: {
          id,
        },
      })
      await manager.update(
        Task,
        {
          receiveCode: sqlData.borrowCode,
        },
        {
          isDelete: true,
        },
      )
      await manager.update(
        Borrow,
        {
          id: id,
        },
        {
          isDelete: true,
        },
      )
    })
  }

  async update(data: Borrow & { assetName: string; typeId: number }) {
    data.borrowOutStatus = '0'
    data.borrowInStatus = '0'
    data.inReason = null
    data.outReason = null
    if (data.assetName) delete data.assetName
    if (data.typeId) delete data.typeId
    // 资产类型
    let sqlData
    await this.connection.transaction(async (manager) => {
      await manager.update(
        Task,
        {
          receiveCode: data.borrowCode,
        },
        {
          taskInStatus: '0',
          taskOutStatus: '0',
          inReason: null,
          outReason: null,
          taskDate: null,
          taskInPerson: null,
          taskInPersonId: null,
          taskOutPerson: null,
          taskOutPersonId: null,
        },
      )
      sqlData = await this.borrowRepository.update(
        {
          id: data.id,
        },
        data,
      )
    })
    return sqlData
  }

  // 更新某个属性
  async updateProperty(code, property, value) {
    return await this.borrowRepository.update(
      {
        borrowCode: code,
      },
      {
        [property]: value,
      },
    )
  }

  // 分页查询
  async getPageList({
    pageRequest: { pageIndex, pageSize },
    borrowCode,
    borrowName,
    borrowInBranch,
    borrowOutBranch,
    borrowInStatus,
    borrowOutStatus,
    receivePerson,
    orgId,
  }) {
    const sqlAllData = await this.borrowRepository.find({
      where: [
        {
          isDelete: IsNull(),
          receiveBranchId: orgId,
          borrowCode: borrowCode,
          borrowName: borrowName,
          borrowInBranch: borrowInBranch,
          borrowOutBranch: borrowOutBranch,
          borrowInStatus: borrowInStatus,
          borrowOutStatus: borrowOutStatus,
          receivePerson: receivePerson,
        },
        {
          isDelete: IsNull(),
          borrowOutBranchId: orgId,
          borrowCode: borrowCode,
          borrowName: borrowName,
          borrowInBranch: borrowInBranch,
          borrowOutBranch: borrowOutBranch,
          borrowInStatus: borrowInStatus,
          borrowOutStatus: borrowOutStatus,
          receivePerson: receivePerson,
        },
      ],
    })
    const sqlData = await this.borrowRepository.find({
      where: [
        {
          isDelete: IsNull(),
          receiveBranchId: orgId,
          borrowCode: borrowCode,
          borrowName: borrowName,
          borrowInBranch: borrowInBranch,
          borrowOutBranch: borrowOutBranch,
          borrowInStatus: borrowInStatus,
          borrowOutStatus: borrowOutStatus,
          receivePerson: receivePerson,
        },
        {
          isDelete: IsNull(),
          borrowOutBranchId: orgId,
          borrowCode: borrowCode,
          borrowName: borrowName,
          borrowInBranch: borrowInBranch,
          borrowOutBranch: borrowOutBranch,
          borrowInStatus: borrowInStatus,
          borrowOutStatus: borrowOutStatus,
          receivePerson: receivePerson,
        },
      ],
      skip: (pageIndex - 1) * pageSize,
      take: pageSize,
      withDeleted: false,
    })
    const resultData = []
    await this.connection.transaction(async (manager) => {
      await sqlData.forEach(async (item) => {
        const assetSqlData = await manager.findOne(Asset, {
          where: {
            assetCode: item.assetCode,
          },
        })
        resultData.push({
          ...item,
          borrowInBranchId: item.borrowInBranchId.toString(),
          borrowOutBranchId: item.borrowOutBranchId.toString(),
          assetName: assetSqlData.assetName,
          typeId: assetSqlData.typeId.toString(),
        })
      })
    })

    return {
      content: resultData,
      total: sqlAllData.length,
    }
  }

  // 获取借用详情 purchaseCode -> *
  async getReceiveDetail(code) {
    const sqlData = await this.borrowRepository.findOne({
      where: {
        assetCode: code,
        isDelete: IsNull(),
      },
    })
    return sqlData
  }
}
